rem ================================================================
rem    TPXMODIE.OPL
rem    16.11.95, Uwe Kallmeyer, 100676.2315@Compuserve.Com
rem ================================================================
rem 
rem This is the TopiX Import/Export module. It contains sourcecode 
rem to access TopiX's internal data structures and a framework to make
rem exporting and importing quite easy.
rem
rem - exporting
rem
rem If you want to build an exporter for a special file format you
rem have to do four things:
rem  1. Add your format to the menu section in starter:. Call texport:
rem     with a 3-char abbreviation and the full name of the format
rem  2. Write a proc e<abbrev>init:(file$) that opens the file, stores
rem     the handle in ofp% and writes the output file header. Pay
rem     attention to open the file in the correct (text/binary)
rem     mode.
rem  3. Write a proc e<abbrev>line:(node%). From here you write the
rem     single line informations. Access them by gtext$:, gfile$:, 
rem     gapp$: and glevel%:
rem  4. Write a proc e<abbrev>exit: that writes the output file footer
rem     and closes ofp%. See the asc/ASCII routines as an example.
rem To simplify the writing of output data the function ol:(string$)
rem is provided, which contains all the stuff around iowrite.
rem 
rem - importing
rem
rem To import data from custom formats you have to do four things:
rem  1. Add your format to the menu section in starter:. Call timport:
rem     with a 3-char abbreviation and the full name of the format
rem  2. Write a proc i<abbrev>init:(file$) that opens the file for 
rem     reading, stores the input file header and reads an input
rem     file header if needed. Pay attention to open the file in 
rem     the correct (text/binary) mode.
rem  3. Write a proc i<abbrev>line:. This reads a line's info from 
rem     the input file and determines text$, file$, level%, flags$
rem     and app$. Then it calls addline:(..)
rem  4. Write a proc i<abbrev>exit: that closes ifp%. See the 
rem     asc/ASCII routines as an example.
rem
rem Of course you can write your im/exporter from scratch if you like
rem or if the provided skeleton does not match your needs. The code
rem in this OPL-file contains all the information you need to 
rem succeed. 
rem
rem If you want to export only one line you will have to address this
rem one line instead of walking through the whole list/tree of lines.
rem to find the node corresponding to the current line use some code
rem along the following lines:
rem       if currlin% > dispptr% or dispptr% <= 0 : return : endif
rem       node% = peekw(uadd(displst%, 2*(currlin% - 1)))
rem and then use node% as argument to gtext$:, gfile$: etc.
rem 
rem Another use for this toolbox could be a printing mechanism for
rem compound documents. You could write an export routine that creates
rem a Macsys macro. This macro reads all Wordfiles into Word and prints 
rem them. Load the created file into Macsys, translate and run.
rem
rem Enjoy.
rem

rem ================================================================
rem main procedure of this module
rem 
PROC starter:
   rem -------------------------------------------------------------
   rem Here is the place for global variables that are global to
   rem importers/exporters
   rem -------------------------------------------------------------
   global cnv2iso%, imexbuf$(255)
   rem -------------------------------------------------------------
	local l%, k%, id%
	while 1
	  minit
		mcard "Export","ASCII",%a,"RTF",%r
	  mcard "Import","ASCII",%A
		mcard "Special","Exit",%x
		k% = menu
		if     k% = %a : texport:("asc", "ASCII")
		elseif k% = %A : timport:("asc", "ASCII")
		elseif k% = %r : texport:("rtf", "RTF")
		elseif k% = %x OR k% = 27 or k% = 0 : return : endif
	endwh
ENDP

rem ================================================================
rem return topix version # this module is compatible with
rem 
PROC tpxtiev:
	return 1.0            rem Version #
ENDP

rem ================================================================
rem returns menu entry for this module
rem 
proc tpxiem$:
	return "IImport / Export" rem key + text
endp

rem ================================================================
rem module entry point, called from TopiX
rem 
proc tpxieg%:           rem module entry point
	starter:
	return 0
endp

rem ================================================================
rem generic import routine. provide your own i<?>init, i<?>line and
rem i<?>exit
rem 
proc timport:(format$, name$)
   local file$(128), ret%
   global ifp%, lvls%(255)
   file$ = "B:\TEST.TXT"
   dInit name$ + "-Import"
   dFile file$, "Source", 0
   ret% = dialog
   if ret% = 0 : return : endif
	 @("i"+format$+"init"):(file$)
   while @("i"+format$+"line"): <> 0 : endwh
	 @("i"+format$+"exit"):
	 ttsetlvl:(ttroot%, 1)
   tt2disp:(ttroot%, 1)
   dirtypg:
   shpg:
   chg% = 1
endp

rem ================================================================
rem call this from i<?>line to actually add a line to outline
rem 
proc addline:(text$, file$, app$, flags%, level%)
   local i%, node%, ret%
   if len(text$) = 0 : return : endif
   node% = ttnew%:(text$, file$)
   if node% = 0 : return : endif
   pokeb uadd(node%, 8), asc(app$)
   pokew uadd(node%, 0), flags%
   ret% = ttins%:(lvls%(level%), 30, node%)
   if ret% = 0
      msg:("Too many subheadings")
      ttfree:(node%)
      return
   endif
   lvls%(level%+1) = peekb(uadd(node%, 4))
   numlins% = numlins% + 1
endp

rem ================================================================
rem generic export routine. provide your own e<?>init, e<?>line and
rem e<?>exit
rem 
proc texport:(format$, name$)
   local file$(128), doall%, ret%, i%, node%
   global ofp%
   doall% = 2
   file$ = "\WRD\*.*"
   dInit name$ + "-Export"
   dChoice doall%, "Current view only", "Yes,No"
   dFile file$, "Destination", 1+16
   ret% = dialog
   if ret% = 0 : return : endif
   if doall% = 1    rem walk thru displist
	    @("e"+format$+"init"):(file$)
	    i% = 0 : while i% < dispptr%
   		   node% = peekw(uadd(displst%, 2*(i%)))
   	     @("e"+format$+"line"):(node%)
		     i% = i% + 1
	    endwh
	    @("e"+format$+"exit"):
   else             rem walk thru tree
	    @("e"+format$+"init"):(file$)
	    exrecl:(ttroot%, format$)
	    @("e"+format$+"exit"):
   endif
   chg% = 1
endp

rem ================================================================
rem private routine that walks through the outline structure
rem recursively
rem 
proc exrecl:(node%, format$)
   local i%
   @("e"+format$+"line"):(node%)
   i% = 0 : while i% < peekb(uadd(node%, 3))
		  if peekw(uadd(peekw(uadd(node%, 13+2*(i%))), 0)) AND 1 <> 0
	       exrecl:(peekw(uadd(node%, 13+2*(i%))), format$)
	    endif
	    i% = i% + 1
	 endwh
endp

rem ================================================================
rem output a line to ofp%
rem 
proc ol:(s$)
   local adr%, buf$(255), ret%
   buf$ = s$
   adr% = uadd(addr(buf$), 1)
   ret% = iowrite(ofp%, adr%, len(buf$))
endp

rem ================================================================
rem return text part of line
rem 
proc gtext$:(n%)
   return peek$(uadd(n%, 13+2*30))
endp

rem ================================================================
rem return flags for line
rem 
proc gflags%:(n%)
   rem   return integer which is a sum of the following:
   rem      2  node is hidden in current view
   rem      4  line is crossed out
   rem      8  line is displayed in italics
   rem     16  line is underlined
   return peekw(uadd(n%, 0))
endp

rem ================================================================
rem return indentation level of line
rem 
proc glevel%:(n%)
   return peekb(uadd(n%, 2))
endp

rem ================================================================
rem returns shortcut char for application
rem 
proc gapp$:(n%)
   return chr$(peekb(uadd(n%, 8)))
endp

rem ================================================================
rem return name of attached file
rem 
proc gfile$:(n%)
   return peek$(uadd(n%, 13+2*30+81))
endp

rem ================================================================
rem converts umlauts to rtf-compatible strings and optionally
rem translates the to ISO-charset
rem 
proc umlcnv$:(s$)
rem \par ae = \'e4   AE=\'c4  oe=\'f6  OE=\'d6  ue=\'fc  UE=\'dc sz=\'df
   local in$(255), ret$(255), i%, c%
   in$ = s$
   i% = 1 : while i% <= len(in$)
      c% = peekb(addr(in$)+i%)
      if cnv2iso% = 1
         if     c% =asc("„") : ret$ = ret$ + "\'e4"
         elseif c% =asc("Ž") : ret$ = ret$ + "\'c4"
         elseif c% =asc("”") : ret$ = ret$ + "\'f6"
         elseif c% =asc("™") : ret$ = ret$ + "\'d6"
         elseif c% =asc("�") : ret$ = ret$ + "\'fc"
         elseif c% =asc("š") : ret$ = ret$ + "\'dc"
         elseif c% =asc("á") : ret$ = ret$ + "\'df"
         else                : ret$ = ret$ + chr$(c%)
         endif
      else
         if loc("„”�Ž™šá", chr$(c%))
            ret$ = ret$ + "\'" + right$("00" + hex$(c%), 2)
         else                
            ret$ = ret$ + chr$(c%)
         endif
      endif
      i% = i% + 1
   endwh
   return ret$
endp

rem ################################################################
rem ################################################################
rem    sample ASCII exporter
rem ################################################################
rem ################################################################

rem ================================================================
rem ASCII export initialization
rem 
proc eascinit:(file$)
   local ret%
   ret% = ioopen(ofp%, file$, $0322)
endp

rem ================================================================
rem ASCII export exit routine
rem 
proc eascexit:
   ioclose(ofp%)
endp

rem ================================================================
rem ASCII export routine for every line
rem 
proc eascline:(n%)
   local lin$(255)
   lin$ = rept$("   ", glevel%:(n%)) + gtext$:(n%)
   ol:(lin$)
rem   --------------------------  filename, application
rem   if asc(gapp$:(n%))
rem      lin$ = rept$("   ", glevel%:(n%)) + "[" + gapp$:(n%) + "] "
rem      lin$ = lin$ + gfile$:(n%)
rem      ol:(lin$)
rem   endif
endp

rem ################################################################
rem ################################################################
rem   sample ASCII importer
rem ################################################################
rem ################################################################

rem ================================================================
rem ASCII import initialization
rem 
proc iascinit:(file$)
   local ret%
   ret% = ioopen(ifp%, file$, $0620)
endp

rem ================================================================
rem ASCII import exit routine
rem 
proc iascexit:
   ioclose(ifp%)
endp

rem ================================================================
rem ASCII import routine for every line
rem 
proc iascline:
   local pbuf$(255), ret%, adr%, text$(255), file$(128), app$(1)
   local i%, level%, flags%
   adr% = uadd(addr(pbuf$), 1)
   ret% = ioread(ifp%, adr%, 255)
   if ret% < 0 : return 0 : endif
   pokeb addr(pbuf$), ret%
   i% = 0 : while peekb(addr(pbuf$)+1+i%) = 32
      i% = i% + 1
   endwh
   level% = (i% / 3) + 1                  rem level% MUST start at 1 !!!
   flags% = 1                             rem Bit 1 MUST be set
   text$ = right$(pbuf$, len(pbuf$)-i%)
   addline:(text$, file$, app$, flags%, level%)
   return 1
endp

rem ################################################################
rem ################################################################
rem    sample RTF exporter
rem ################################################################
rem ################################################################

rem ================================================================
rem RTF export initialization
rem 
proc ertfinit:(file$)
   local ret%, i%, iso%
   dinit "Conversion options"
   dChoice iso%, "Charset", "8-Bit ASCII,ISO"
   dialog
   cnv2iso% = iso% - 1   
   ret% = ioopen(ofp%, file$, $0322)
   ol:("{\rtf1 \pca")
   ol:("{\fonttbl") 
   ol:("{\f0 \fmodern Courier;}")
   ol:("{\f24 \froman CG Times;}")
   ol:("}{\stylesheet")
   ol:("{\qj \sa40 \sl240 \f24 \fs20 Normal;}")
   i% = 1 : while i% <= 30
      ol:("{" + rtfmkfm$:(i%) + "heading " + num$(i%, 2) + ";}")
      i% = i% + 1
   endwh
   imexbuf$ = "}"
endp

rem ================================================================
rem private procedure. builds format string for given level
rem 
proc rtfmkfm$:(l%)
   local buf$(255)
   buf$ = "\s" + num$(l%, 2) + " \li" + num$(567.0*l%, 5)
   buf$ = buf$ + " \sa120 \sl240 \keepn \f24 \b "
   return buf$
endp      

rem ================================================================
rem RTF export exit routine
rem 
proc ertfexit:
   ol:("}")
   ioclose(ofp%)
endp

rem ================================================================
rem RTF export routine for every line
rem 
proc ertfline:(n%)
   local lin$(255)
   lin$ = imexbuf$ + "\pard \plain " + rtfmkfm$:(glevel%:(n%))
   lin$ = lin$ + umlcnv$:(gtext$:(n%)) + "\par"
   imexbuf$ = ""
   ol:(lin$)
endp


